package com.lefevre.cms.service.theme.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.lefevre.cms.bean.theme.Forum;
import com.lefevre.cms.bean.theme.Layout;
import com.lefevre.cms.bean.theme.ThemeData;
import com.lefevre.cms.bean.theme.Themes;
import com.lefevre.cms.mapper.ForumMapper;
import com.lefevre.cms.mapper.LayoutMapper;
import com.lefevre.cms.mapper.TemplateMapper;
import com.lefevre.cms.service.besa.DaoSupport;
import com.lefevre.cms.service.theme.ThemeService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 模板管理实现类
 *
 * @author Lefevre
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ThemeServiceImpl extends DaoSupport<Layout> implements ThemeService {

    @Resource
    private LayoutMapper layoutMapper;
    @Resource
    private ForumMapper forumMapper;
    @Resource
    private TemplateMapper templatesMapper;


    /**
     * 查询所有已导入的模板
     *
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Themes> findAllTemplates() {
        return templatesMapper.selectList(null);
    }

    /**
     * 查询系统当前使用的模板目录(目录为空时返回default)
     *
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public String findTemplateDir() {
        Themes themes = templatesMapper.selectOne(new LambdaQueryWrapper<Themes>().eq(Themes::getUses, true));
        if (themes != null) {
            return themes.getDirName();
        }
        return "default";
    }


    /**
     * 查询系统当前使用的模板目录(目录为空时返回default) - 缓存
     *
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "'findTemplateDir_default'")
    public String findTemplateDir_cache() {
        return this.findTemplateDir();
    }


    /**
     * 保存模板
     *
     * @param themes
     * @param layoutList 默认布局数据
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public void saveTemplate(Themes themes, List<Layout> layoutList) {
        templatesMapper.insert(themes);
        //生成模板文件
        if (layoutList != null && layoutList.size() > 0) {
            for (Layout layout : layoutList) {
                layoutMapper.insert(layout);
            }
        }
    }

    /**
     * 修改模板
     *
     * @param themes
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer updateTemplate(Themes themes) {
        return templatesMapper.updateById(themes);
    }

    /**
     * 删除模板
     *
     * @param dirName 模板目录
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer deleteTemplate(String dirName) {
        //删除模板目录
        int i = templatesMapper.delete(new LambdaUpdateWrapper<Themes>().eq(Themes::getDirName, dirName));
        //删除布局
        i += layoutMapper.delete(new LambdaUpdateWrapper<Layout>().eq(Layout::getDirName, dirName));
        //删除版块
        i += forumMapper.delete(new LambdaUpdateWrapper<Forum>().eq(Forum::getDirName, dirName));
        return i;
    }

    /**
     * 设置当前模板为使用
     *
     * @param dirName 模板目录
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer useTemplate(String dirName) {
        templatesMapper.update(null, new LambdaUpdateWrapper<Themes>()
                .set(Themes::getUses, false));

        return templatesMapper.update(null, new LambdaUpdateWrapper<Themes>()
                .set(Themes::getUses, true)
                .eq(Themes::getDirName, dirName));
    }

    /**
     * 根据模板目录查询模板
     *
     * @param dirName 模板目录名称
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Themes findTemplateByDirName(String dirName) {
        return templatesMapper.selectOne(new LambdaQueryWrapper<Themes>().eq(Themes::getDirName, dirName));
    }

    /**
     * 根据模板目录查询模板 - 缓存
     *
     * @param dirName 模板目录名称
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "'findTemplatebyDirName_'+#dirName")
    public Themes findTemplateByDirName_cache(String dirName) {
        return this.findTemplateByDirName(dirName);
    }
    /**-----------------------------------------  站点栏目    ---------------------------------------------**/

    /**
     * 修改站点栏目
     *
     * @param columnList_json 站点栏目JSON格式数据
     * @param dirName         模板目录名称
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer updateColumn(String columnList_json, String dirName) {
        return templatesMapper.update(null, new LambdaUpdateWrapper<Themes>()
                .set(Themes::getColumns, columnList_json)
                .eq(Themes::getDirName, dirName));
    }


    /**-------------------------------------------  布局   ---------------------------------------------**/

    /**
     * 根据布局Id查询布局
     *
     * @param layoutId 布局Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Layout findLayoutByLayoutId(String layoutId) {
        return layoutMapper.selectById(layoutId);
    }

    /**
     * 根据模板目录查询最大布局排序号
     *
     * @param dirName 模板目录名称
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Integer findMaxLayoutSortByDirName(String dirName) {
        return layoutMapper.selectList(new LambdaQueryWrapper<Layout>()
                .eq(Layout::getDirName, dirName)
                .orderByDesc(Layout::getSort)).get(0).getSort();
    }

    /**
     * 根据布局文件查询布局
     *
     * @param dirName    模板目录
     * @param layoutFile 布局模板
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Layout> findLayoutByLayoutFile(String dirName, String layoutFile) {
        return layoutMapper.selectList(new LambdaQueryWrapper<Layout>()
                .eq(Layout::getDirName, dirName)
                .like(Layout::getLayoutFile, layoutFile));
    }

    /**
     * 根据模板目录查询布局
     *
     * @param dirName 模板目录名称
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Layout> findLayout(String dirName) {
        return layoutMapper.selectList(new LambdaQueryWrapper<Layout>().eq(Layout::getDirName, dirName));
    }

    /**
     * 根据模板目录名称和布局类型查询布局
     *
     * @param dirName 模板目录名称
     * @param type    布局类型
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Layout> findLayout(String dirName, Integer type) {
        return layoutMapper.selectList(new LambdaQueryWrapper<Layout>()
                .eq(Layout::getDirName, dirName)
                .eq(Layout::getType, type));
    }

    /**
     * 根据模板目录名称和布局类型查询布局 - 缓存
     *
     * @param dirName 模板目录名称
     * @param type    布局类型
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "#dirName+'_findLayout_'+#type")
    public List<Layout> findLayout_cache(String dirName, Integer type) {
        return this.findLayout(dirName, type);
    }

    /**
     * 根据模板目录名称和引用代码前缀查询布局
     *
     * @param dirName             模板目录
     * @param referenceCodePrefix 模块引用代码前缀  如:Brand_Show_
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Layout> findLayoutByReferenceCode(String dirName, String referenceCodePrefix) {
        return layoutMapper.selectList(new LambdaQueryWrapper<Layout>()
                .eq(Layout::getDirName, dirName)
                .like(Layout::getReferenceCode, referenceCodePrefix));
    }

    /**
     * 根据模板目录名称和布局类型和引用代码查询布局
     *
     * @param dirName       模板目录
     * @param type          布局类型
     * @param referenceCode 模块引用代码
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Layout findLayoutByReferenceCode(String dirName, Integer type, String referenceCode) {
        return layoutMapper.selectOne(new LambdaQueryWrapper<Layout>()
                .eq(Layout::getDirName, dirName)
                .eq(Layout::getType, type)
                .eq(Layout::getReferenceCode, referenceCode));
    }

    /**
     * 根据模板目录名称和布局类型和引用代码查询布局 - 缓存
     *
     * @param dirName       模板目录
     * @param type          布局类型
     * @param referenceCode 模块引用代码
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "#dirName+'_findLayoutByReferenceCode_'+#type+'-'+#referenceCode")
    public Layout findLayoutByReferenceCode_cache(String dirName, Integer type, String referenceCode) {
        return this.findLayoutByReferenceCode(dirName, type, referenceCode);
    }

    /**
     * 根据模板目录名称查询'更多'
     *
     * @param dirName   模板目录
     * @param forumData 版块数据
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Layout> findMore(String dirName, Integer forumData) {
        return layoutMapper.selectList(new LambdaQueryWrapper<Layout>()
                .eq(Layout::getDirName, dirName)
                .eq(Layout::getType, 3)//3.更多
                .eq(Layout::getForumData, forumData));
    }

    /**
     * 根据商品分类Id查询布局
     *
     * @param dirName       模板目录名称
     * @param productTypeId 商品分类Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Layout findLayoutByProductTypeId(String dirName, Long productTypeId) {
        return layoutMapper.selectOne(new LambdaQueryWrapper<Layout>()
                .eq(Layout::getId, dirName)
                .eq(Layout::getType, productTypeId));
    }

    /**
     * 根据商品分类Id查询布局 - 缓存
     *
     * @param dirName       模板目录名称
     * @param productTypeId 商品分类Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "#dirName+'_findLayoutByProductTypeId_'+#productTypeId")
    public Layout findLayoutByProductTypeId_cache(String dirName, Long productTypeId) {
        return this.findLayoutByProductTypeId(dirName, productTypeId);
    }

    /**
     * 添加布局
     *
     * @param layout 布局
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public void saveLayout(Layout layout) {
        layoutMapper.insert(layout);
    }

    /**
     * 修改布局
     *
     * @param layout 布局
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer updateLayoutById(Layout layout) {
        return layoutMapper.updateById(layout);
    }

    /**
     * 修改布局名称
     *
     * @param dirName       模板目录
     * @param newSort       排序
     * @param type          布局类型
     * @param referenceCode 模块引用代码
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public void updateLayoutName(String newName, Integer newSort, String dirName, Integer type, String referenceCode) {
        layoutMapper.update(null, new LambdaUpdateWrapper<Layout>()
                .set(Layout::getName, newName)
                .set(Layout::getSort, newSort)
                .eq(Layout::getDirName, dirName)
                .eq(Layout::getType, type)
                .eq(Layout::getReferenceCode, referenceCode));
    }

    /**
     * 根据布局Id删除布局
     *
     * @param dirName  模板目录名称
     * @param layoutId 布局Id
     * @return
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer deleteLayoutByLayoutId(String dirName, String layoutId) {
        //删除版块
        this.deleteForumByLayoutId(dirName, layoutId);
        return layoutMapper.delete(new LambdaUpdateWrapper<Layout>()
                .eq(Layout::getId, layoutId)
                .eq(Layout::getDirName, dirName));
    }


    /**-----------------------------------------  版块    ---------------------------------------------**/
    /**
     * 查询模板版块
     *
     * @param dirName    模板目录名称
     * @param layoutType 布局类型
     * @param layoutFile 布局文件
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Forum> findForum(String dirName, Integer layoutType, String layoutFile) {
        return forumMapper.selectList(new LambdaQueryWrapper<Forum>()
                .eq(Forum::getDirName, dirName)
                .eq(Forum::getLayoutType, layoutType)
                .eq(Forum::getLayoutFile, layoutFile));
    }

    /**
     * 查询模板版块 - 缓存
     *
     * @param dirName    模板目录名称
     * @param layoutType 布局类型
     * @param layoutFile 布局文件
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "#dirName+'_findForum_'+#layoutType+'-'+#layoutFile")
    public List<Forum> findForum_cache(String dirName, Integer layoutType, String layoutFile) {
        return this.findForum(dirName, layoutType, layoutFile);
    }


    /**
     * 根据布局Id查询模板版块
     *
     * @param dirName      模板目录名称
     * @param layoutId布局Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Forum> findForumByLayoutId(String dirName, String layoutId) {
        return forumMapper.selectList(new LambdaQueryWrapper<Forum>()
                .eq(Forum::getDirName, dirName)
                .eq(Forum::getLayoutId, layoutId));
    }

    /**
     * 根据布局Id查询模板版块 - 缓存
     *
     * @param dirName      模板目录名称
     * @param layoutId布局Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "#dirName+'_findForumByLayoutId_'+#layoutId")
    public List<Forum> findForumByLayoutId_cache(String dirName, String layoutId) {
        return this.findForumByLayoutId(dirName, layoutId);
    }


    /**
     * 根据模板目录名称和引用代码查询版块
     *
     * @param dirName       模板目录
     * @param referenceCode 模块引用代码
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Forum findForum(String dirName, String referenceCode) {
        return forumMapper.selectOne(new LambdaQueryWrapper<Forum>()
                .eq(Forum::getDirName, dirName)
                .eq(Forum::getReferenceCode, referenceCode));
    }

    /**
     * 根据模板目录名称和引用代码查询版块 - 缓存
     *
     * @param dirName       模板目录
     * @param referenceCode 模块引用代码
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "#dirName+'_findForum_'+#referenceCode")
    public Forum findForum_cache(String dirName, String referenceCode) {
        return this.findForum(dirName, referenceCode);
    }

    /**
     * 根据版块Id查询版块
     *
     * @param forumId 版块Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Forum findForumById(Integer forumId) {
        return forumMapper.selectById(forumId);
    }

    /**
     * 根据版块Id查询版块 - 缓存
     *
     * @param forumId 版块Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "templateServiceBean_cache", key = "'findForumById_'+#dirName")
    public Forum findForumById_cache(Integer forumId) {
        return this.findForumById(forumId);
    }

    /**
     * 根据模板目录名称和模板字段查询版块是否存在
     *
     * @param dirname    模板目录名称
     * @param layoutId   布局Id
     * @param layoutType 布局类型
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public boolean getForumThere(String dirName, String layoutId, Integer layoutType) {
        Long aLong = forumMapper.selectCount(new LambdaQueryWrapper<Forum>()
                .eq(Forum::getLayoutId, layoutId)
                .eq(Forum::getDirName, dirName)
                .eq(Forum::getLayoutType, layoutType));
        return aLong > 0;
    }

    /**
     * 根据模块引用代码前缀查询模块引用代码当前类别的所有值
     *
     * @param dirName             模板目录
     * @param referenceCodePrefix 模块引用代码前缀  如:Brand_Show_
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Forum> findForumByReferenceCodePrefix(String dirName, String referenceCodePrefix) {
        return forumMapper.selectList(new LambdaQueryWrapper<Forum>()
                .eq(Forum::getDirName, dirName)
                .like(Forum::getReferenceCode, referenceCodePrefix));
    }

    /**
     * 添加版块
     *
     * @param forum 版块
     * @return
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public void saveForum(Forum forum) {
        forumMapper.insert(forum);
    }

    /**
     * 修改版块
     *
     * @param forum 版块
     * @return
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer updateForum(Forum forum) {
        return forumMapper.updateById(forum);
    }


    /**
     * 根据布局Id删除版块
     *
     * @param dirName  模板目录名称
     * @param layoutId 布局Id
     * @return
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer deleteForumByLayoutId(String dirName, String layoutId) {
        return forumMapper.delete(new LambdaUpdateWrapper<Forum>()
                .eq(Forum::getLayoutId, layoutId)
                .eq(Forum::getDirName, dirName));
    }

    /**
     * 根据版块Id删除版块
     *
     * @param forumId 版块Id
     * @return
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public Integer deleteForumByForumId(Integer forumId) {
        return forumMapper.deleteById(forumId);
    }

    /**
     * 根据模板目录查询版块
     *
     * @param dirName 模板目录名称
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<Forum> findForumByDirName(String dirName) {
        return forumMapper.selectList(new LambdaQueryWrapper<Forum>()
                .eq(Forum::getDirName, dirName));
    }
    /**-----------------------------------------  数据    ---------------------------------------------**/

    /**
     * 保存模板数据
     *
     * @param themeData 模板数据
     */
    @CacheEvict(value = "templateServiceBean_cache", allEntries = true)
    public void saveTemplateData(ThemeData themeData) {
        if (themeData.getThemes() != null) {
            templatesMapper.insert(themeData.getThemes());
        }
        //布局数据
        List<Layout> layoutList = themeData.getLayoutList();
        if (layoutList != null && layoutList.size() > 0) {
            for (Layout layout : layoutList) {
                layoutMapper.insert(layout);
            }
        }
        //版块数据
        List<Forum> forumList = themeData.getForumList();
        if (forumList != null && forumList.size() > 0) {
            for (Forum forum : forumList) {
                forumMapper.insert(forum);
            }
        }
    }
}
